package com.ll.base.exception;


import com.ll.base.enums.ResultCodeEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Data
@Slf4j
@SuppressWarnings("serial")
public class CustomRunTimeException extends RuntimeException {

    private String errorCode;
    private String errorMsg;
    private String errorDetail;
    private Exception exception;
    private Object result;
    private Object[] objectNames;

    public CustomRunTimeException(String key, String msg, Object[] objectNames) {
        super(msg);
        this.errorCode = key;
        this.errorMsg = msg;
        this.objectNames = objectNames;
    }

    public CustomRunTimeException(ResultCodeEnum resultCodeEnum) {
        super(resultCodeEnum.getMsg());
        this.errorCode = resultCodeEnum.getCode();
        this.errorMsg = resultCodeEnum.getMsg();
    }

    public CustomRunTimeException(ResultCodeEnum resultCodeEnum, String errorMsgValue) {
        super(errorMsgValue);
        this.errorCode = resultCodeEnum.getCode();
        this.errorMsg = errorMsgValue;
    }

    public CustomRunTimeException(ResultCodeEnum resultCodeEnum, Object[] objectName) {
        super(resultCodeEnum.getMsg());
        this.errorCode = resultCodeEnum.getCode();
        this.errorMsg = resultCodeEnum.getMsg();
        this.objectNames = objectName;
    }

    public CustomRunTimeException(ResultCodeEnum resultCodeEnum, Object[] objectName, Object result) {
        super(resultCodeEnum.getMsg());
        this.errorCode = resultCodeEnum.getCode();
        this.errorMsg = resultCodeEnum.getMsg();
        this.objectNames = objectName;
        this.result = result;
    }

    public CustomRunTimeException(ResultCodeEnum resultCodeEnum, String errorMsgValue, Object[] objectName, Object result) {
        super(errorMsgValue);
        this.errorCode = resultCodeEnum.getCode();
        this.errorMsg = errorMsgValue;
        this.objectNames = objectName;
        this.result = result;
    }

    public CustomRunTimeException(ResultCodeEnum resultCodeEnum, String errorMsgValue, Object[] objectName) {
        super(errorMsgValue);
        this.errorCode = resultCodeEnum.getCode();
        this.errorMsg = errorMsgValue;
        this.objectNames = objectName;
    }

    private void printMessage(Object result) {
        if (null != result) {
            if (result instanceof Exception){
                log.error(String.format("exception【%s】", getStackMsg((Exception) result)));
            }
            else{
                log.error(String.format("result【%s】", result.toString()));
            }
        }
    }

    private String getStackMsg(Exception e) {
        StringBuffer sb = new StringBuffer();
        sb.append(e.toString()).append("\n");
        StackTraceElement[] stackArray = e.getStackTrace();
        for (int i = 0; i < stackArray.length; i++) {
            StackTraceElement element = stackArray[i];
            sb.append(element.toString() + "\n");
        }
        return sb.toString();
    }

    /**
     * 校验数据是否为空，并且抛出异常
     *
     * @param object
     * @param objName
     */
    public static void checkNull(Object object, String objName) {
        if (object == null) {
            throw new CustomRunTimeException(ResultCodeEnum.DATA_NOT_EXIST_ERROR, new Object[]{objName});
        }
    }


    public static void conditionCheckNull(boolean condition, Object object, String objName) {
        if (condition && object == null) {
            throw new CustomRunTimeException(ResultCodeEnum.DATA_EXIST_ERROR, new Object[]{objName});
        }
    }
    /**
     * 校验字符串是否为空，并且抛出异常
     *
     * @param object
     * @param objName
     */
    public static void checkNull(String object, String objName) {
        if (object == null) {
            throw new CustomRunTimeException(ResultCodeEnum.DATA_EXIST_ERROR, new Object[]{objName});
        }
    }

    /**
     * 校验数据是否为空,并且返回异常对象
     *
     * @param object
     * @param objName
     */
    public static void checkNull(Object object, String objName, Object result) {
        if (object == null) {
            throw new CustomRunTimeException(ResultCodeEnum.DATA_EXIST_ERROR, new Object[]{objName}, result);
        }
    }

    /**
     * 参数错误
     *
     * @param objName
     */
    public static void parameterError(String objName) {
        throw new CustomRunTimeException(ResultCodeEnum.PARAM_VALUE_INVALID, new Object[]{objName});
    }

    /**
     * 校验数据是否不为空
     *
     * @param object
     * @param objName
     */
    public static void checkNotNull(Object object, String objName) {
        if (object != null) {
            throw new CustomRunTimeException(ResultCodeEnum.DATA_NOT_EXIST_ERROR, new Object[]{objName});
        }
    }

    public static void checkRegex(String body, String regex, String name) {
        checkNull(body, name);
        if (!body.matches(regex)) {
            throw new CustomRunTimeException(ResultCodeEnum.DATA_EXCEPTION_ERROR, new Object[]{name});
        }

    }

    @Override
    public Throwable fillInStackTrace() {
        return super.fillInStackTrace();
    }

}